package com.padgett.resourcemanagement.invoice;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.labs.repackaged.org.json.JSONException;
import com.google.appengine.labs.repackaged.org.json.JSONObject;
import com.padgett.resourcemanagement.data.ClientDAO;

/**
 * Pay invoice.
 * 
 * @author andyleung
 * 
 */
@SuppressWarnings("serial")
public class AjaxPayInvoiceServlet extends HttpServlet{
	private static final Logger logger=Logger.getLogger(AjaxPayInvoiceServlet.class.getName());
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		String invoiceId=req.getParameter("invoiceId");
		String amountString=req.getParameter("Amount");
		String paidDateString=req.getParameter("PaidDate");
		String payee=req.getParameter("Payee");
		String accountant=req.getParameter("Accountant");
		String methodOfPayment=req.getParameter("MethodOfPayment");
		String note=req.getParameter("Note");
		
		UserService userService=UserServiceFactory.getUserService();
		User user=userService.getCurrentUser();
		String userEmail=user.getEmail();
		Key key=KeyFactory.stringToKey(invoiceId);
		// Check if invoice is already fully paid.
		List<Entity> invoiceReceipts=ClientDAO.getInvoiceReceipts(key);
		double paid=0.0;
		for(Entity paidReceipt:invoiceReceipts){
			paid+=(paidReceipt.getProperty("Amount")!=null?(Double)paidReceipt.getProperty("Amount"):0.0);
		}
		List<Entity> invoiceLineItems=ClientDAO.getInvoiceLineItems(key);
		double invoiceTotal=0.0;
		for(Entity invoiceLineItem:invoiceLineItems){
			if(invoiceLineItem.getProperty("Total")!=null){
				double itemTotal=(Double)(invoiceLineItem.getProperty("Total"));
				invoiceTotal+=itemTotal;
			}
		}
		double difference=invoiceTotal-paid;
		double amount=Double.parseDouble(amountString);
		JSONObject response=new JSONObject();
		if(amount<=difference){
			Key invoiceReceiptKey=new KeyFactory.Builder(KeyFactory.stringToKey(invoiceId))
			.getKey();
			Entity invoiceReceipt=new Entity("InvoiceReceipt",invoiceReceiptKey);
			invoiceReceipt.setProperty("CreatedBy", userEmail);
			invoiceReceipt.setProperty("CreatedDate", new Date(System.currentTimeMillis()));
			invoiceReceipt.setProperty("LastModifiedBy", userEmail);
			invoiceReceipt.setProperty("LastModifiedDate", new Date(System.currentTimeMillis()));

			invoiceReceipt.setProperty("MethodOfPayment", methodOfPayment);
			invoiceReceipt.setProperty("Payee", payee);
			invoiceReceipt.setProperty("Amount", amount);
			invoiceReceipt.setProperty("Accountant", accountant);
			Date paidDate=null;
			if(paidDateString!=null&&!paidDateString.isEmpty()){
				paidDate=new Date(Long.parseLong(paidDateString));
				invoiceReceipt.setProperty("PaidDate", paidDate);
			}
			if(note!=null){
				invoiceReceipt.setUnindexedProperty("Note", new Text(note));
			}
			Key savedKey=ClientDAO.saveEntity(invoiceReceipt);
			// If invoice is fully paid, mark invoice as paid.
			if(amount==difference){
				Entity invoice=ClientDAO.loadEntity(key);
				invoice.setProperty("FullyPaidDate", new Date(System.currentTimeMillis()));
				invoice.setProperty("FullyPaid", Boolean.TRUE);
				ClientDAO.saveEntity(invoice);
			}
			try{
				response.put("success", Boolean.TRUE);
				response.put("invoiceId", KeyFactory.keyToString(savedKey));
			}catch(JSONException je){
				je.printStackTrace();
				logger.severe(je.getMessage());
			}
		}else{
			// Paid
			try{
				response.put("success", Boolean.FALSE);
				response.put("error", "Payment is more than owing or Invoice is already fully paid.");
			}catch(JSONException je){
				je.printStackTrace();
				logger.severe(je.getMessage());
			}
		}
		resp.getWriter().write(response.toString());
	}

}
